﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

using Blog.TemplateEngine;
using Blog.TemplateEngine.Helpers;

namespace Blog.TemplateViewEngine.Functions
{
    class UrlFunction : IFunction
    {
        protected INode Compile(Parser parser, Token token)
        {
            string[] source = token.Content.SmartSplitAndTrim(' ');
            IDictionary<string, IParameter> parameters = token.Content.ParseNamedVariables(':');

            IParameter action = null;
            IParameter controller = null;
            Dictionary<string, IParameter> valueDictionary = new Dictionary<string, IParameter>();

            foreach (KeyValuePair<string, IParameter> param in parameters)
            {
                switch (param.Key)
                {
                    case "action":
                        {
                            action = param.Value;
                        }
                        break;
                    case "controller":
                        {
                            controller = param.Value;
                        }
                        break;
                    default:
                        {
                            valueDictionary[param.Key] = param.Value;
                        }
                        break;
                }
            }

            if (action == null)
            {
                throw new TemplateException("'url' requires an action parameter: url action:'action' [controler:'controller'] [name1:value1 name2:value2]");
            }

            return new UrlNode(action, controller, valueDictionary);
        }

        INode IFunction.Compile(Parser parser, Token token)
        {
            return Compile(parser, token);
        }
    }

    class UrlNode : INode
    {
        UrlHelper mUrlHelper;
        IParameter mActionName;
        IParameter mControllerName;
        IDictionary<string, IParameter> mParameters;

        public UrlNode(IParameter actionName, IParameter controllerName, IDictionary<string, IParameter> parameters)
        {
            mActionName = actionName;
            mControllerName = controllerName;
            mParameters = parameters;
        }

        protected string Render(Context context)
        {
            ViewContext viewContext = (ViewContext)context["Mvc.ViewContext"];

            RouteValueDictionary values = new RouteValueDictionary();
            foreach (KeyValuePair<string, IParameter> value in mParameters)
            {
                values.Add(value.Key, value.Value.AsString(context));
            }

            mUrlHelper = new UrlHelper(viewContext);
            string url;

            if (mControllerName == null)
            {
                url = mUrlHelper.Action(mActionName.AsString(context), values);
            }
            else
            {
                url = mUrlHelper.Action(mActionName.AsString(context), mControllerName.AsString(context), values);
            }

            return url ?? string.Empty;
        }

        string INode.Render(Context context)
        {
            return Render(context);
        }
    }
}
